#include "queue.h"
#include "doxon.h"

#include  <_null.h> // For NULL

Queue::Queue() {
    lock();
    first = NULL;
    len = 0;
    unlock();
}

Queue::~Queue() {
    lock();
    Elem* temp;
    while ( first != NULL )
    {
        temp = first;
        first = first->next;
        delete temp;
        len--;
    }
    unlock();
}

int Queue::size() const {
    return len;
}

PCB* Queue::get() {
    if ( first == NULL )
        return NULL;
    lock();
    len--;
    Elem* temp = first;
    PCB*  tmp_pcb= first->pcb;
    first = first->next;
    delete temp;
    unlock();
    return tmp_pcb;
}

void Queue::put(PCB* pcb) {
    lock();
    Elem **dp = &first;

    if ( pcb == NULL ) {
        unlock();
        return;
    }

    while( (*dp) != NULL )
    {
        //Proveravamo da li ima duplikata
        if( (*dp)->pcb == pcb ) { unlock(); return; }
        dp = &((*dp)->next);
    }
    (*dp) = new Elem();
    (*dp)->next = NULL;
    (*dp)->pcb = pcb;
    len++;
    unlock();
}

void Queue::del(PCB* pcb) {
    Elem* prev    = first;
    Elem* next    = first->next;

    if ( pcb == NULL ) {
        return;
    }

    lock();

    if ( first->pcb == pcb ) {
        Elem* tmp;
        tmp = first;
        first = first->next;
        delete tmp;
    } 
    else {
        while (1) {
            if ( next == NULL )
                break;
            if ( next->pcb == pcb ) {
                prev->next = next->next;
                delete next;
                break;
            }
            prev = next;
            next = next->next;
        }
    }
    
    unlock();
}
